#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "securec.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#include "wifi_device.h"
#include "wifi_error_code.h"
#include "wifi_linked_info.h"
#include "station_info.h"
#include "wifi_event.h"
#include "wifi_error_code.h"

#define DEF_TIMEOUT 15
#define ONE_SECOND 1
#define SELECT_WIFI_SECURITYTYPE WIFI_SEC_TYPE_OPEN
#define OD_DELAY_100 100
#define OD_DELAY_200 200
#define WIFI_NAME "ESP32_STA"
#define WIFI_PWD "12345678"

static int result;
static int g_ConnectSuccess = 0;
static WifiErrorCode wifi_error;
static WifiEvent g_wifiEventHandler = {0};
static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info);

static void WiFiInit(void)
{
    printf("<--Wifi Init-->\r\n");
    g_wifiEventHandler.OnWifiConnectionChanged = OnWifiConnectionChangedHandler;
    wifi_error = RegisterWifiEvent(&g_wifiEventHandler);
    if (wifi_error != WIFI_SUCCESS) {
        printf("register wifi event fail!\r\n");
    } else {
        printf("register wifi event succeed!\r\n");
    }
}


static int WaitConnectResult(void)
{
    int ConnectTimeout = DEF_TIMEOUT;
    while (ConnectTimeout > 0) {
        sleep(1);
        ConnectTimeout--;
        if (g_ConnectSuccess == 1) {
            printf("WaitConnectResult:wait success[%d]s\n", (DEF_TIMEOUT - ConnectTimeout));
            break;
        }
    }
    if (ConnectTimeout <= 0) {
        printf("WaitConnectResult:timeout!\n");
        return 0;
    }
    return 1;
}

static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info)
{
    (void)info;
    if (state > 0) {
        g_ConnectSuccess = 1;
        printf("callback function for wifi connect\r\n");
    } else {
        g_ConnectSuccess = 0;
        printf("connect wifi_error, please check wifi config, state:%d, try connect again\r\n", state);
        esp_wifi_connect();
    }
    return;
}

static void WifiConnect(const char *ssid, const char *psk)
{
    WifiScanInfo *info = NULL;
    unsigned int size = WIFI_SCAN_HOTSPOT_LIMIT;
    WifiDeviceConfig select_ap_config = {0};
    osDelay(OD_DELAY_200);
    printf("<--System Init-->\r\n");
    WiFiInit();
    if (EnableWifi() != WIFI_SUCCESS) {
        printf("EnableWifi failed, wifi_error = %d\n", wifi_error);
        return;
    }
    if (IsWifiActive() == 0) {
        printf("Wifi station is not actived.\n");
        return;
    }
    strcpy_s(select_ap_config.ssid, sizeof(select_ap_config.ssid), ssid);
    strcpy_s(select_ap_config.preSharedKey, sizeof(select_ap_config.preSharedKey), psk);
    printf("%s %s \r\n", select_ap_config.ssid, select_ap_config.preSharedKey);
    select_ap_config.securityType = SELECT_WIFI_SECURITYTYPE;
    if (AddDeviceConfig(&select_ap_config, &result) == WIFI_SUCCESS) {
        if (ConnectTo(result) == WIFI_SUCCESS && WaitConnectResult() == 1) {
            printf("WiFi connect succeed!\r\n");
        } else {
            printf("connecting fail\r\n");
            return;
        }
    }
    osDelay(OD_DELAY_100);
    return;
}

void WifiStaTask(void)
{
    WifiConnect(WIFI_NAME,WIFI_PWD);
    while (1){
        osDelay(OD_DELAY_100);
    }
}

void WifiStaDemo(void)
{
    osThreadAttr_t attr;
    attr.name = "WIFI_STA_TASK";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 0x1000;
    attr.priority = 25;
    if (osThreadNew((osThreadFunc_t)WifiStaTask, NULL, &attr) == NULL) {
        printf("Failed to create thread!\n");
    }
}

APP_FEATURE_INIT(WifiStaDemo);